%{
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "Parser.h"
#include "Scanner.tab.hpp"
int yyCMDline_num = 1;
%}
DIGIT [0-9]
SPACES [ \t]+
INTEGER [+-]?{DIGIT}+
DOUBLE1 [+-]?{DIGIT}+"."{DIGIT}*
DOUBLE2 [+-]?"."{DIGIT}+
DOUBLE3 [+-]?{DIGIT}+"."{DIGIT}*[eE][+-]?{DIGIT}+
DOUBLE4 [+-]?{DIGIT}+[eE][+-]?{DIGIT}+
DOUBLE5 [+-]?"."{DIGIT}+[eE][+-]?{DIGIT}+
DOUBLE {DOUBLE1}|{DOUBLE2}|{DOUBLE3}|{DOUBLE4}|{DOUBLE5}
STRING "\""[A-z0-9,._\/\-\+\=\)\(\\ *]*"\""
DICTOKEN [A-Z][A-z0-9_]*
DEFTOKEN [a-z][A-z0-9_]*
INTEGERRANGE {INTEGER}|{INTEGER}":"{INTEGER}

%%

"\n" { yyCMDline_num++; }

"\/\/" { while(yyinput() != '\n') ; yyCMDline_num++; }

"\/\*" { 
  for (;;) {
    int c;
    while ((c = yyinput()) != '*')
    if (c == '\n') yyCMDline_num++;
    if (yyinput() == '/') break;
    else unput(yytext[yyleng-1]);
  }
}

"-"|"+"|"*"|"["|"]"|"^"|"{"|"}"|"="|","|"("|")"|":"|";"|"."|"/" { return *yyCMDtext; }

{SPACES} {}

{INTEGER} { yyCMDlval.ival = atoi(yyCMDtext); return IntConstant; }

{DOUBLE} { yyCMDlval.dval = atof(yyCMDtext); return DoubleConstant ; }

{STRING} {
  char* str = new char[strlen(yyCMDtext)-1]; 
  str[0] = 0;
  strncat(str, yyCMDtext+1, strlen(yyCMDtext)-2);
  yyCMDlval.sval = str; 
  return String; 
}

#define { return tdefine; }

cos { return tcos; }

sin { return tsin; }

tan { return ttan; }

acos { return tacos; }

asin { return tasin; }

atan { return tatan; }

sqrt { return tsqrt; }

"\["{SPACES}*({DICTOKEN}{SPACES}*)*{SPACES}*"\]" {
  char* str = new char[strlen(yyCMDtext)-1];
  str[0] = 0;
  strncat(str, yyCMDtext+1, strlen(yyCMDtext)-2);
  yyCMDlval.sval = str;
  return TokenList;
}

{DICTOKEN} {
  yyCMDlval.token = Parser::instance().getDictionaryToken(yyCMDtext);
  return Symbol; 
}

{DEFTOKEN} {
  yyCMDlval.token = Parser::instance().createDictionaryToken(yyCMDtext);
  return DefinedSymbol; 
}

"\["({SPACES}*)({INTEGER}{SPACES}*)*({SPACES}*)"\]" {
  char* str = new char[strlen(yyCMDtext)-1];
  str[0] = 0;
  strncat(str, yyCMDtext+1, strlen(yyCMDtext)-2);
  yyCMDlval.sval = str;
  return IntegerList;
}

"\["{SPACES}*({DOUBLE}{SPACES}*)*{SPACES}*"\]" {
  char* str = new char[strlen(yyCMDtext)-1];
  str[0] = 0;
  strncat(str, yyCMDtext+1, strlen(yyCMDtext)-2);
  yyCMDlval.sval = str;
  return DoubleList;
}

"\["{SPACES}*({STRING}{SPACES}*)*{SPACES}*"\]" {
  char* str = new char[strlen(yyCMDtext)-1];
  str[0] = 0;
  strncat(str, yyCMDtext+1, strlen(yyCMDtext)-2);
  yyCMDlval.sval = str;
  return StringList;
}

"\["{SPACES}*({INTEGERRANGE}{SPACES}*)*{SPACES}*"\]" {
  char* str = new char[strlen(yyCMDtext)-1];
  str[0] = 0;
  strncat(str, yyCMDtext+1, strlen(yyCMDtext)-2);
  yyCMDlval.sval = str;
  return IntegerRange;
}

<<EOF>> { return EoF; }

%%

void yyCMDerror(const char*) {
  fprintf(stderr, "Error: syntax error near line %d\n", yyCMDline_num);
  exit(1);
}

int yyCMDwrap() {
  return 1;
}
